﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YJKRevitKernel.CurveUtility.ColinearCurveGroup;
using YJKCopyModel.CommonTrans;
using YJKPresentation.Utils;

namespace YJKCopyModel.DuctFastModel
{
	[Grouper(GrouperName = "DuctGrouper")]
	internal class DuctGrouper : IDataGrouper
	{
		public List<RevitModelRequest> GroupData(InputRequest inputRequest)
		{
			List<RevitModelRequest> list = new List<RevitModelRequest>();
			DuctRequest ductRequest = inputRequest as DuctRequest;
			DuctFastModelRequest ductFastModelRequest = new DuctFastModelRequest();
			Dictionary<int, DuctInfo> ductCurve = this.GetDuctCurve(ductRequest);
			this.CalculateWidth(ref ductCurve);
			JudgeGroup judgeGroup = new JudgeGroup();
			List<DuctHeight> lstDuctHeights = ductRequest.LstDuctHeights;
			judgeGroup.DuctLineTextGroup(lstDuctHeights, ref ductCurve);
			List<List<Curve>> list2 = new List<List<Curve>>();
			bool bFange = DuctFormData.m_bFange;
			if (bFange)
			{
				try
				{
					list2 = judgeGroup.FitCurveArea(ductRequest);
				}
				catch (Exception)
				{
				}
			}
			else
			{
				list2.AddRange(ductRequest.LstBlockInfos);
			}
			judgeGroup.DuctCurveGroupByFit(list2, ref ductCurve);
			List<Dictionary<int, DuctInfo>> list3 = judgeGroup.DuctDivideSystem(ductCurve);
			int num = 0;
			bool bIsSystem = DuctFormData.m_bIsSystem;
			if (bIsSystem)
			{
				Curve curveBySys = ductRequest.CurveBySys;
				Dictionary<int, DuctInfo> item = new Dictionary<int, DuctInfo>();
				foreach (Dictionary<int, DuctInfo> dictionary in list3)
				{
					foreach (KeyValuePair<int, DuctInfo> keyValuePair in dictionary)
					{
						bool flag = judgeGroup.CheckTwoCurveIsSame(keyValuePair.Value.ParaleCurve.FirstParalelCurve, curveBySys) || judgeGroup.CheckTwoCurveIsSame(keyValuePair.Value.ParaleCurve.SecondParalelCurve, curveBySys);
						if (flag)
						{
							item = dictionary;
						}
					}
				}
				list3 = new List<Dictionary<int, DuctInfo>>();
				list3.Add(item);
			}
			foreach (Dictionary<int, DuctInfo> dictionary2 in list3)
			{
				DuctInfo ductInfo = new DuctInfo();
				double num2 = double.MinValue;
				List<RevitModelRequest> list4 = new List<RevitModelRequest>();
				foreach (KeyValuePair<int, DuctInfo> keyValuePair2 in dictionary2)
				{
					list4.Add(new DuctFastModelRequest
					{
						DuctInfo = keyValuePair2.Value,
						SystemNumber = num
					});
					bool bAuto = DuctFormData.m_bAuto;
					if (bAuto)
					{
						bool flag2 = keyValuePair2.Value.Height == null || Convert.ToDouble(keyValuePair2.Value.Height.dDuctHeight) <= 0.0;
						if (flag2)
						{
							double num3 = 0.0;
							double num4 = 0.0;
							List<int> list5 = new List<int>();
							this.GetDSizeLoop(dictionary2, keyValuePair2.Value, ref num3, ref list5, true);
							this.GetDSizeLoop(dictionary2, keyValuePair2.Value, ref num4, ref list5, false);
							keyValuePair2.Value.Height = new DuctHeight();
							bool flag3 = num4 > 0.0 && num3 > 0.0;
							if (flag3)
							{
								keyValuePair2.Value.Height.dDuctHeight = Math.Min(num4, num3).ToString();
							}
							else
							{
								keyValuePair2.Value.Height.dDuctHeight = Math.Max(num4, num3).ToString();
							}
						}
					}
					bool bAppoint = DuctFormData.m_bAppoint;
					if (bAppoint)
					{
						bool flag4 = keyValuePair2.Value.Width > num2;
						if (flag4)
						{
							ductInfo = keyValuePair2.Value;
							num2 = keyValuePair2.Value.Width;
						}
					}
					else
					{
						bool flag5 = keyValuePair2.Value.Width * Convert.ToDouble(keyValuePair2.Value.Height.dDuctHeight) > num2;
						if (flag5)
						{
							ductInfo = keyValuePair2.Value;
							num2 = keyValuePair2.Value.Width * Convert.ToDouble(keyValuePair2.Value.Height.dDuctHeight);
						}
					}
				}
				foreach (RevitModelRequest revitModelRequest in list4)
				{
					DuctFastModelRequest ductFastModelRequest2 = (DuctFastModelRequest)revitModelRequest;
					bool flag6 = ductFastModelRequest2.DuctInfo.Index == ductInfo.Index;
					if (flag6)
					{
						ductFastModelRequest2.DuctInfo.ISMainPipe = true;
					}
				}
				list.AddRange(list4);
				num++;
			}
			return list;
		}

		private bool CheckIsRightFitCurves(List<Curve> curves)
		{
			bool flag = curves.IsEmpty<Curve>();
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = !this.CheckCurvesIsLines(curves);
				if (flag2)
				{
					result = true;
				}
				else
				{
					List<Curve> list = this.MergeLines(curves);
					bool flag3 = list.Count != 4;
					if (flag3)
					{
						result = true;
					}
					else
					{
						ToleranceManger toleranceManger = ToleranceManger.GetToleranceManger();
						double tolerance = toleranceManger.GetTolerance("末端快模-角度公差");
						for (int i = 0; i < list.Count - 1; i++)
						{
							try
							{
								Line line = list[i] as Line;
								bool flag4 = i == 0;
								Line line2;
								if (flag4)
								{
									line2 = (list[list.Count - 1] as Line);
								}
								else
								{
									line2 = (list[i + 1] as Line);
								}
								bool flag5 = !Geometry.IsEqual(line.Direction.AngleTo(line2.Direction), Math.PI*.5, tolerance);
								if (flag5)
								{
									return false;
								}
							}
							catch
							{
								return false;
							}
						}
						double num = Math.Min(list[0].Length, list[1].Length);
						bool flag6 = num <= Common.MMToFeet(50.0);
						result = !flag6;
					}
				}
			}
			return result;
		}

		private List<Curve> MergeLines(List<Curve> lineCurves)
		{
			bool flag = lineCurves == null || lineCurves.Count <= 0;
			List<Curve> result;
			if (flag)
			{
				result = new List<Curve>();
			}
			else
			{
				ColinearGroupManager colinearGroupManager = new ColinearGroupManager(lineCurves);
				List<List<Curve>> colinearGroup = colinearGroupManager.GetColinearGroup();
				bool flag2 = colinearGroup == null || colinearGroup.Count <= 0;
				if (flag2)
				{
					result = lineCurves;
				}
				else
				{
					List<Curve> list = new List<Curve>();
					foreach (List<Curve> list2 in colinearGroup)
					{
						bool flag3 = list2 != null && list2.Count > 0;
						if (flag3)
						{
							list.AddRange(list2);
						}
					}
					result = list;
				}
			}
			return result;
		}

		private bool CheckCurvesIsLines(List<Curve> curves)
		{
			bool flag = curves.IsEmpty<Curve>();
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				foreach (Curve curve in curves)
				{
					bool flag2 = curve is Line;
					if (!flag2)
					{
						return false;
					}
				}
				result = true;
			}
			return result;
		}

		private void GetDSizeLoop(Dictionary<int, DuctInfo> inputSystem, DuctInfo tmpInfo, ref double dHeight, ref List<int> litInts, bool bLOrR)
		{
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			if (bLOrR)
			{
				dictionary = tmpInfo.GetLstConnectStart;
			}
			else
			{
				dictionary = tmpInfo.GetLstConnectEnd;
			}
			bool flag = dictionary.Count == 0;
			if (!flag)
			{
				List<int> rightDuctInfo = this.GetRightDuctInfo(inputSystem, dictionary, tmpInfo);
				foreach (int num in rightDuctInfo)
				{
					bool flag2 = !litInts.Contains(num);
					if (flag2)
					{
						litInts.Add(num);
						DuctInfo ductInfo = new DuctInfo();
						inputSystem.TryGetValue(num, out ductInfo);
						bool flag3 = ductInfo != null && ductInfo.Height != null && Convert.ToDouble(ductInfo.Height.dDuctHeight) > 0.0;
						if (flag3)
						{
							dHeight = Convert.ToDouble(ductInfo.Height.dDuctHeight);
							break;
						}
						this.GetDSizeLoop(inputSystem, ductInfo, ref dHeight, ref litInts, bLOrR);
					}
				}
			}
		}

		private List<int> GetRightDuctInfo(Dictionary<int, DuctInfo> inputSystem, Dictionary<int, int> lstInt, DuctInfo tmpInfo)
		{
			bool flag = lstInt == null || lstInt.Count <= 0;
			List<int> result;
			if (flag)
			{
				result = new List<int>();
			}
			else
			{
				XYZ ductInfoVector = this.GetDuctInfoVector(tmpInfo);
				bool flag2 = ductInfoVector == null;
				if (flag2)
				{
					result = new List<int>();
				}
				else
				{
					Dictionary<int, double> dictionary = new Dictionary<int, double>();
					foreach (KeyValuePair<int, int> keyValuePair in lstInt)
					{
						DuctInfo ductInfo = new DuctInfo();
						inputSystem.TryGetValue(keyValuePair.Key, out ductInfo);
						bool flag3 = ductInfo == null;
						if (!flag3)
						{
							XYZ ductInfoVector2 = this.GetDuctInfoVector(ductInfo);
							bool flag4 = ductInfoVector2 == null;
							if (!flag4)
							{
								double num = ductInfoVector.AngleTo(ductInfoVector2) * 180.0 / Math.PI;
								bool flag5 = num > 90.0;
								if (flag5)
								{
									num = 180.0 - num;
								}
								dictionary.Add(keyValuePair.Key, num);
							}
						}
					}
					Dictionary<int, double> dictionary2 = this.SortDicByValue(dictionary);
					result = dictionary2.Keys.ToList<int>();
				}
			}
			return result;
		}

		private Dictionary<int, double> SortDicByValue(Dictionary<int, double> dic)
		{
			bool flag = dic == null || dic.Count <= 0;
			Dictionary<int, double> result;
			if (flag)
			{
				result = new Dictionary<int, double>();
			}
			else
			{
				Dictionary<int, double> dictionary = (from o in dic
				orderby o.Value
				select o).ToDictionary((KeyValuePair<int, double> o) => o.Key, (KeyValuePair<int, double> o) => o.Value);
				result = dictionary;
			}
			return result;
		}

		private XYZ GetDuctInfoVector(DuctInfo duct)
		{
			bool flag = duct == null || duct.ParaleCurve == null || duct.ParaleCurve.LocationCurve == null;
			XYZ result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = (duct.ParaleCurve.LocationCurve.GetEndPoint(1) - duct.ParaleCurve.LocationCurve.GetEndPoint(0)).Normalize();
			}
			return result;
		}

		public Dictionary<int, DuctInfo> GetDuctCurve(DuctRequest ductRequest)
		{
			Dictionary<int, DuctInfo> dictionary = new Dictionary<int, DuctInfo>();
			DuctInfo ductInfo = new DuctInfo();
			int num = 0;
			foreach (DoubleParaleCurve paraleCurve in ductRequest.LstDoubleParaleCurves)
			{
				ductInfo = new DuctInfo();
				ductInfo.ParaleCurve = paraleCurve;
				ductInfo.Index = num;
				ductInfo.GetStartEndPoints.Add(ductInfo.ParaleCurve.LocationCurve.GetEndPoint(0));
				ductInfo.GetStartEndPoints.Add(ductInfo.ParaleCurve.LocationCurve.GetEndPoint(1));
				dictionary.Add(ductInfo.Index, ductInfo);
				num++;
			}
			return dictionary;
		}

		public void CalculateWidth(ref Dictionary<int, DuctInfo> lstDuctInfos)
		{
			foreach (KeyValuePair<int, DuctInfo> keyValuePair in lstDuctInfos)
			{
				keyValuePair.Value.Width = this.GetDistance(keyValuePair.Value.ParaleCurve);
			}
		}

		private double GetDistance(DoubleParaleCurve curves)
		{
			IntersectionResult intersectionResult = new IntersectionResult();
			intersectionResult = curves.SecondParalelCurve.Project(curves.FirstParalelCurve.GetEndPoint(0));
			XYZ xyz = null;
			bool flag = intersectionResult != null;
			if (flag)
			{
				xyz = intersectionResult.XYZPoint;
			}
			return curves.FirstParalelCurve.GetEndPoint(0).DistanceTo(xyz);
		}
	}
}
